/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.farmcode.web.project;

import com.farmcode.api.runtime.FARMCodeContext;
import com.farmcode.api.security.User;
import com.farmcode.base.dao.DAOException;
import com.farmcode.base.manager.FacadeException;
import com.farmcode.base.web.Identity;
import com.farmcode.console.api.RequiredValueExeception;
import com.farmcode.console.api.business.DatabaseManager;
import com.farmcode.console.api.business.LanguageManager;
import com.farmcode.console.api.business.PackageTemplateManager;
import com.farmcode.console.api.business.StatusManager;
import com.farmcode.console.api.business.custom.ExtProjectManager;
import com.farmcode.console.api.business.custom.ExtPropertyManager;
import com.farmcode.console.api.model.*;
import com.farmcode.web.BaseFARMCodeBacking;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.bean.RequestScoped;
import javax.inject.Named;

/**
 *
 * @author Oscar Ivan Prado
 */
@Named(value = "projectBackingBean")
@RequestScoped
public class ProjectBackingBean extends BaseFARMCodeBacking {

    public static final String PROJECT_SESSION_NAME = ProjectBackingBean.class.getName() + ".project";
    public static final String STATUSES_SESSION_NAME = ProjectBackingBean.class.getName() + ".statuses";
    public static final String DATABASES_SESSION_NAME = ProjectBackingBean.class.getName() + ".databases";
    public static final String LANGUAGES_SESSION_NAME = ProjectBackingBean.class.getName() + ".languajes";
    public static final String PACKAGES_TEMPLATES_SESSION_NAME = ProjectBackingBean.class.getName() + ".packageTemplates";
    
    public static final String SELECTED_STATUS = ProjectBackingBean.class.getName() + ".selectedStatus";
    public static final String SELECTED_DATABASE = ProjectBackingBean.class.getName() + ".selectedDatabase";
    public static final String SELECTED_LANGUAGE = ProjectBackingBean.class.getName() + ".selectedLanguage";
    public static final String SELECTED_PACKAGE_TEMPLATE = ProjectBackingBean.class.getName() + ".selectedTemplate";
    
    public static final String GO_MODIFY_PROJECT = "goModifyProject";
    public static final String GO_CREATE_PROJECT = "goCreateProject";

    private List<Project> assignedProjects;
    private List<Status> statuses;
    private List<Database> databases;
    private List<Language> languages;
    private List<PackageTemplate> packageTemplates;
    
    private Long selectedStatus;
    private Long selectedDatabase;
    private Long selectedLanguage;
    private Long selectedTemplate;
    
    @EJB
    private ExtProjectManager projectManager;
    @EJB
    private StatusManager statusManager;
    @EJB
    private DatabaseManager databaseManager;
    @EJB 
    private LanguageManager languageManager;
    @EJB
    private PackageTemplateManager packageTemplateManager;
    @EJB
    private ExtPropertyManager extPropertyManager;
    
    /**
     * Creates a new instance of Project
     */
    public ProjectBackingBean() {
    }
    
    public void save() {
        try {
            
            hydrate();
            projectManager.create(getProject());
            createDefaultProperties();
            clear();
            showMessage(java.util.ResourceBundle.getBundle("com/farmcode/i18n/message").getString("project.message.save"));
            
        } catch (FacadeException ex) {
            showError(ex.getMessage());
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }catch(RequiredValueExeception ex){
             showError(ex.getMessage());
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    private void createDefaultProperties() throws FacadeException{
        try {
            
            boolean jdbcManager = false;
            if(getSession().getValue(DatasourceBackingBean.JDBC_DATABASE_EXPLORER_SELECTED) != null)
                jdbcManager = Boolean.parseBoolean( getSession().getValue(DatasourceBackingBean.JDBC_DATABASE_EXPLORER_SELECTED).toString());
            
            String plugin = getSession().getValue(FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER);
            String host = getSession().getValue(FARMCodeContext.HOST);
            String driver = getSession().getValue(FARMCodeContext.DRIVER);
            String user = getSession().getValue(FARMCodeContext.USER);
            String password = getSession().getValue(FARMCodeContext.PASSWORD);
            String schema = getSession().getValue(FARMCodeContext.SCHEMA);
            extPropertyManager.createJDBCProperties(jdbcManager, plugin, host, driver, schema, user, password, getProject());
            
        } catch (FacadeException ex) {
            throw ex;
        }
    }
    
    public String goModifyProject(Project project){
        try {
            
            setProject(project);
            setSelectedDatabase(project.getDatabase().getId());
            setSelectedLanguage(project.getLanguage().getId());
            setSelectedTemplate(project.getPackageTemplate().getId());
            setSelectedStatus(project.getStatus().getId());
            Property property = extPropertyManager.getPropertyByName(project, FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER);
            getSession().setValue(FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER, property.getValue());
            
            if(property.getValue().equals(DatasourceBackingBean.JDBC_DATABASE_EXPLORER)){
                
                String driver = extPropertyManager.getPropertyByName(project, FARMCodeContext.DRIVER).getValue();
                String host = extPropertyManager.getPropertyByName(project, FARMCodeContext.HOST).getValue();
                String user = extPropertyManager.getPropertyByName(project, FARMCodeContext.USER).getValue();
                String password = extPropertyManager.getPropertyByName(project, FARMCodeContext.PASSWORD).getValue();
                String schema = extPropertyManager.getPropertyByName(project, FARMCodeContext.SCHEMA).getValue();
                
                getSession().setValue(DatasourceBackingBean.JDBC_DATABASE_EXPLORER_SELECTED, true);
                getSession().setValue(FARMCodeContext.DRIVER, driver);
                getSession().setValue(FARMCodeContext.HOST, host);
                getSession().setValue(FARMCodeContext.USER, user);
                getSession().setValue(FARMCodeContext.PASSWORD, password);
                getSession().setValue(FARMCodeContext.SCHEMA, schema);
                
            }else{
                getSession().setValue(DatasourceBackingBean.JDBC_DATABASE_EXPLORER_SELECTED, false);
            }
            
            
        } catch (DAOException ex) {
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return GO_MODIFY_PROJECT;
    }
    
    public String goCreateProject(){
        clear();
        return GO_CREATE_PROJECT;
    }
    
    private void hydrate() throws RequiredValueExeception{
       
        Status status = getStatusById(getSelectedStatus());
        Database database = getDatabaseById(getSelectedDatabase());
        Language language = getLanguageById(getSelectedLanguage());
        PackageTemplate packageTemplate = getPackageTemplateById(getSelectedTemplate());
        
        if (status == null) {
                throw new RequiredValueExeception("Select status");
        }
        
        if(database == null){
               throw new RequiredValueExeception("Select database");
        }
        
        if(language == null){
               throw new RequiredValueExeception("Select language");
        }
        
        if(packageTemplate == null){
               throw new RequiredValueExeception("Select template");
        }
        
        getProject().setStatus(status);
        getProject().setDatabase(database);
        getProject().setLanguage(language);
        getProject().setPackageTemplate(packageTemplate);
        
    }

    public void modify() {
        try {
            
            hydrate();
            projectManager.store(getProject());
            
            Property property = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER);
            getSession().setValue(FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER, property.getValue());
            
            if(property.getValue().equals(DatasourceBackingBean.JDBC_DATABASE_EXPLORER)){
                
                Property driver = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.DRIVER);
                Property host = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.HOST);
                Property user = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.USER);
                Property password = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.PASSWORD);
                Property schema = extPropertyManager.getPropertyByName(getProject(), FARMCodeContext.SCHEMA);
                
                driver.setValue((String)getSession().getValue(FARMCodeContext.DRIVER));
                host.setValue((String)getSession().getValue(FARMCodeContext.HOST));
                user.setValue((String)getSession().getValue(FARMCodeContext.USER));
                password.setValue((String)getSession().getValue(FARMCodeContext.PASSWORD));
                schema.setValue((String)getSession().getValue(FARMCodeContext.SCHEMA));

                extPropertyManager.store(driver);
                extPropertyManager.store(host);
                extPropertyManager.store(user);
                extPropertyManager.store(password);
                extPropertyManager.store(schema);
            }
            
            showMessage(java.util.ResourceBundle.getBundle("com/farmcode/i18n/message").getString("project.message.modify"));
            
        } catch (DAOException ex) {
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FacadeException ex) {
            showError(ex.getMessage());
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }catch(RequiredValueExeception ex){
             showError(ex.getMessage());
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void clear(){
        setProject(null);
        setSelectedDatabase(-1L);
        setSelectedLanguage(-1L);
        setSelectedStatus(-1L);
        setSelectedTemplate(-1L);
        getSession().setValue(FARMCodeContext.OBJECT_INFO_PLUGIN_MANAGER, "");
        getSession().setValue(DatasourceBackingBean.JDBC_DATABASE_EXPLORER_SELECTED, false);
        getSession().setValue(FARMCodeContext.DRIVER, null);
        getSession().setValue(FARMCodeContext.HOST, null);
        getSession().setValue(FARMCodeContext.USER, null);
        getSession().setValue(FARMCodeContext.PASSWORD, null);
        getSession().setValue(FARMCodeContext.SCHEMA, null);
    }

    /**
     * @return the assignedProjects
     */
    public List<Project> getAssignedProjects() {
        try {
            if (assignedProjects == null) {
                assignedProjects = projectManager.getProjectsByUser("");
                if (getIdentity() != null && getIdentity().getUser() != null) {
                    String userName = ((User) (getIdentity().getUser())).getName();
//                    System.out.println()
                }
            }
        } catch (DAOException ex) {
            Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            showError(ex.getMessage());
        }
        return assignedProjects;
    }

    /**
     * @param assignedProjects the assignedProjects to set
     */
    public void setAssignedProjects(List<Project> assignedProjects) {
        this.assignedProjects = assignedProjects;
    }
    
     @Override
    public Identity getIdentity() {
        return new Identity((Object) new User("oiprado", true));
    }

    private Status getStatusById(Long id) {
        Status status = null;
        if (id != null) {
            for (Status var : getStatuses()) {
                if (var.getId().equals(id)) {
                    status = var;
                    break;
                }
            }
        }
        return status;
    }

    /**
     * @return the statuses
     */
    public List<Status> getStatuses() {
        if (statuses == null) {
            try {
                setStatuses(statusManager.find());
            } catch (FacadeException ex) {
                Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
                showError(ex.getMessage());
            }
        }
        return statuses;
    }

    /**
     * @param statuses the statuses to set
     */
    public void setStatuses(List<Status> statuses) {
        this.statuses = statuses;
        getSession().setValue(STATUSES_SESSION_NAME, statuses);
    }

    /**
     * @return the selectedStatus
     */
    public Long getSelectedStatus() {
        if (getSession().getValue(SELECTED_STATUS) != null) {
            selectedStatus = getSession().getValue(SELECTED_STATUS);
        }
        return selectedStatus;
    }

    /**
     * @param selectedStatus the selectedStatus to set
     */
    public void setSelectedStatus(Long selectedStatus) {
        this.selectedStatus = selectedStatus;
        getSession().setValue(SELECTED_STATUS, selectedStatus);
    }

    /**
     * @return the databases
     */
    public List<Database> getDatabases() {
        if(getSession().getValue(DATABASES_SESSION_NAME) != null){
            databases = getSession().getValue(DATABASES_SESSION_NAME);
        }else{
            try {
                setDatabases(databaseManager.find());
            } catch (FacadeException ex) {
                Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
                showError(ex.getMessage());
            }
        }
        return databases;
    }

    /**
     * @param databases the databases to set
     */
    public void setDatabases(List<Database> databases) {
        this.databases = databases;
        getSession().setValue(DATABASES_SESSION_NAME, databases);
    }

    /**
     * @return the languages
     */
    public List<Language> getLanguages() {
        if(getSession().getValue(LANGUAGES_SESSION_NAME) != null){
            languages = getSession().getValue(LANGUAGES_SESSION_NAME);
        }else{
            try {
                setLanguages(languageManager.find());
            } catch (FacadeException ex) {
                Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return languages;
    }

    /**
     * @param languages the languages to set
     */
    public void setLanguages(List<Language> languages) {
        this.languages = languages;
        getSession().setValue(LANGUAGES_SESSION_NAME, languages);
    }

    /**
     * @return the packageTemplates
     */
    public List<PackageTemplate> getPackageTemplates() {
        if(getSession().getValue(PACKAGES_TEMPLATES_SESSION_NAME) != null){
            packageTemplates = getSession().getValue(PACKAGES_TEMPLATES_SESSION_NAME);
        }else{
            try {
                setPackageTemplates(packageTemplateManager.find());
            } catch (FacadeException ex) {
                Logger.getLogger(ProjectBackingBean.class.getName()).log(Level.SEVERE, null, ex);
                showError(ex.getMessage());
            }
        }
        return packageTemplates;
    }

    /**
     * @param packageTemplates the packageTemplates to set
     */
    public void setPackageTemplates(List<PackageTemplate> packageTemplates) {
        this.packageTemplates = packageTemplates;
        getSession().setValue(PACKAGES_TEMPLATES_SESSION_NAME, packageTemplates);
    }

    /**
     * @return the selectedDatabase
     */
    public Long getSelectedDatabase() {
        if(getSession().getValue(SELECTED_DATABASE) != null){
            selectedDatabase = getSession().getValue(SELECTED_DATABASE);
        }
        return selectedDatabase;
    }

    /**
     * @param selectedDatabase the selectedDatabase to set
     */
    public void setSelectedDatabase(Long selectedDatabase) {
        this.selectedDatabase = selectedDatabase;
        getSession().setValue(SELECTED_DATABASE, selectedDatabase);
    }

    /**
     * @return the selectedLanguage
     */
    public Long getSelectedLanguage() {
        if(getSession().getValue(SELECTED_LANGUAGE) != null){
            selectedLanguage = getSession().getValue(SELECTED_LANGUAGE);
        }
            
        return selectedLanguage;
    }

    /**
     * @param selectedLanguage the selectedLanguage to set
     */
    public void setSelectedLanguage(Long selectedLanguage) {
        this.selectedLanguage = selectedLanguage;
        getSession().setValue(SELECTED_LANGUAGE, selectedLanguage);
    }

    /**
     * @return the selectedTemplate
     */
    public Long getSelectedTemplate() {
        if(getSession().getValue(SELECTED_PACKAGE_TEMPLATE) != null){
            selectedTemplate = getSession().getValue(SELECTED_PACKAGE_TEMPLATE);
        }
        return selectedTemplate;
    }

    /**
     * @param selectedTemplate the selectedTemplate to set
     */
    public void setSelectedTemplate(Long selectedTemplate) {
        this.selectedTemplate = selectedTemplate;
        getSession().setValue(SELECTED_PACKAGE_TEMPLATE, selectedTemplate);
    }

    private Database getDatabaseById(Long selectedDatabase) {
        Database database = null;
        if(selectedDatabase != null){
            for(Database var : getDatabases()){
                if(var.getId().equals(selectedDatabase)){
                    database = var;
                    break;
                }
            }
        }
        
        return database;
    }

    private Language getLanguageById(Long selectedLanguage) {
        Language language = null;
        if(selectedLanguage != null){
            for (Language var : getLanguages()) {
                if(var.getId().equals(selectedLanguage)){
                    language = var;
                    break;
                }
            }
        }
        return language;
    }

    private PackageTemplate getPackageTemplateById(Long selectedTemplate) {
        PackageTemplate packageTemplate = null;
        if(selectedTemplate != null){
            for (PackageTemplate var : getPackageTemplates()) {
                if(var.getId().equals(selectedTemplate)){
                    packageTemplate = var;
                    break;
                }
            }
        }
        return packageTemplate;
    }
    
}
